/*
 * Title:        CloudScheduler Toolkit
 * Description:  a Toolkit for Modeling and Simulation of Job Scheduling and Resource Provisioning in Cloud System
 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
 * Author:       Fuhui Wu
 *
 * Copyright (c) 2013-2014, The National University of Defense Technology, China
 */

package org.nudt.jCloud.simulation;

import java.util.HashMap;
import java.util.Map;

import org.nudt.jCloud.workload.Job;
import org.nudt.jCloud.workload.Task;

public class SchedBatchSet {
	private Map<User, Map<Job, Map<Double, Batch>>> batchSet;
	
	public SchedBatchSet(){
		setBatchSet(new HashMap<User, Map<Job, Map<Double, Batch>>>());
	}
	
	public void add(Task task){
		Job job = task.getJob();
		double taskDuration = TaskExecution.execution(task, task.getSlot());
		User user = job.getXJob().getWl().getUser();
		if(batchSet.containsKey(user)){
			Map<Job, Map<Double, Batch>> jobBatches = batchSet.get(user);
			if(jobBatches.containsKey(job)){
				Map<Double, Batch> batchList = jobBatches.get(job);
				if(batchList.containsKey(taskDuration)){
					batchList.get(taskDuration).add(task);
				}else{
					Batch batch = new Batch(job);
					batch.add(task);
					batch.setDuration(taskDuration);
					batchList.put(taskDuration, batch);
				}
			}else{
				Batch batch = new Batch(job);
				batch.add(task);
				batch.setDuration(taskDuration);
				Map<Double, Batch> durationBatch = new HashMap<Double, Batch>();
				durationBatch.put(taskDuration, batch);
				jobBatches.put(job, durationBatch);
			}
		}else{
			Map<Job, Map<Double, Batch>> jobBatches = new HashMap<Job, Map<Double, Batch>>();
			jobBatches.put(job, new HashMap<Double, Batch>());
			Batch batch = new Batch(job);
			batch.add(task);
			batch.setDuration(taskDuration);
			Map<Double, Batch> durationBatch = new HashMap<Double, Batch>();
			durationBatch.put(taskDuration, batch);
			jobBatches.put(job, durationBatch);
			batchSet.put(user, jobBatches);
		}
	}
	
	public void removeTask(Task task){
		Job job = task.getJob();
		User user = job.getXJob().getWl().getUser();
		double taskDuration = TaskExecution.execution(task, task.getSlot());
		if(batchSet.containsKey(user)==false){
			throw new RuntimeException("no user: cannot remove an unAssigned task.");
		}else{
			if(batchSet.get(user).containsKey(job)==false){
				throw new RuntimeException("no job: cannot remove an unAssigned task.");
			}else{
				if(batchSet.get(user).get(job).containsKey(taskDuration)==false){
					throw new RuntimeException("no duration: cannot remove an unAssigned task.");
				}else{
					batchSet.get(user).get(job).get(taskDuration).remove(task);
					if(batchSet.get(user).get(job).get(taskDuration).size()<=0){
						batchSet.get(user).get(job).remove(taskDuration);
						if(batchSet.get(user).get(job).size()<=0){
							batchSet.get(user).remove(job);
							if(batchSet.get(user).size()<=0){
								batchSet.remove(user);
							}
						}
					}
				}
				
			}
		}
	}

	public Map<User, Map<Job, Map<Double, Batch>>> getBatchSet() {
		return batchSet;
	}

	public void setBatchSet(Map<User, Map<Job, Map<Double, Batch>>> batchSet) {
		this.batchSet = batchSet;
	}

}
